package com.koron.device.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.WorkbookUtil;
import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.annocation.CasUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.interceptor.OrderByInterceptor;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.CommonUtils;
import com.koron.common.core.util.TreeUtils;
import com.koron.device.bean.ClassifyBean;
import com.koron.device.bean.EquipmentBackup;
import com.koron.device.bean.EquipmentBackupQuery;
import com.koron.device.bean.dto.ClassifyDto;
import com.koron.device.bean.dto.EquipmentBackupDto;
import com.koron.device.listener.BackUpLinstener;
import com.koron.device.mapper.EquipmentBackupMapper;
import com.koron.device.service.EquipmentBackupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @anthor chenyiwei
 * @date 2022/4/1
 */

@Slf4j
@RequestMapping("/equipmentBackup")
@RestController
@Api(tags = "备品备件")
public class EquipmentBackupController {

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    @Autowired
    private EquipmentBackupService equipmentbackupservice;


    @GetMapping("/getById")
    @ApiOperation(value = "查询单个备件")
    public Response getById(@CasUser @ApiIgnore EamUser user, String id) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "getById", Response.class, id);
    }

    @GetMapping("/getClassifyById")
    @ApiOperation(value = "查询单个分类")
    public Response getClassifyById(@CasUser @ApiIgnore EamUser user, String classifyid) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "getClassifyById", Response.class, classifyid);
    }

    @GetMapping("/serch")
    @ApiOperation(value = "多条件分页查询")
    public Response<PageInfo<EquipmentBackup>> serch(@CasUser @ApiIgnore EamUser user, EquipmentBackupQuery query) {
        OrderByInterceptor.setOrderBy(query.getOrders());
        PageHelper.startPage(query.getPage(), query.getPageSize());
        List<EquipmentBackup> list = ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "serch", List.class, query);
        return Response.success(new PageInfo<>(list), (long) list.size());
    }

    @GetMapping("/serchnew")
    @ApiOperation(value = "多条件分页查询new")
    public Response<PageInfo<EquipmentBackup>> serchnew(@CasUser @ApiIgnore EamUser user, EquipmentBackupQuery query) {
        List<EquipmentBackup> list = ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "serchnew", List.class, query);
        return Response.success(new PageInfo<>(list), (long) list.size());
    }

    @PostMapping("/add")
    @ApiOperation(value = "新增")
    public Response add(@CasUser @ApiIgnore EamUser user, @RequestBody EquipmentBackup backup) {
        backup.setId(CodeTools.getCode32());
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "add", Response.class, backup);
    }


    @PostMapping("/bindBatch")
    @ApiOperation(value = "批量绑定")
    public Response bindBatch(@CasUser @ApiIgnore EamUser user, @RequestBody List<EquipmentBackup> bindList) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "bindBatch", Response.class, bindList);
    }

    @PostMapping("/noBindBatch")
    @ApiOperation(value = "批量解绑")
    public Response noBindBatch(@CasUser @ApiIgnore EamUser user, @RequestBody List<String> bingId) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "noBindBatch", Response.class, bingId);
    }

    @PostMapping("/update")
    @ApiOperation(value = "修改并保存")
    public Response update(@CasUser @ApiIgnore EamUser user, @RequestBody EquipmentBackup backup) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "update", Response.class, backup);
    }

    @PostMapping("/commit")
    @ApiOperation(value = "提交")
    public Response commit(@CasUser @ApiIgnore EamUser user, @RequestBody EquipmentBackup backup) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "commit", Response.class, backup);

    }

    @PostMapping("/delete")
    @ApiOperation(value = "删除")
    public Response delete(@CasUser @ApiIgnore EamUser user, @RequestBody EquipmentBackup backup) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "delete", Response.class, backup);

    }


    @GetMapping("/getTree")
    @ApiOperation(value = "查询分类树")
    public Response getTree(@CasUser @ApiIgnore EamUser user, ClassifyBean query) {
        List<ClassifyBean> list = ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "getTree", List.class, query);
        return Response.success(list);
    }

    @GetMapping("/getTreeList")
    @ApiOperation(value = "查询分类列表")
    public Response getTreeList(@CasUser @ApiIgnore EamUser user) {
        List<ClassifyBean> list = ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "getTreeList", List.class);
        return Response.success(list);
    }


    @ApiOperation(value = "新增分类")
    @PostMapping("/insertClassify")
    public Response insertClassify(@CasUser @ApiIgnore EamUser user, @RequestBody ClassifyBean classifyBean) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "insertClassify", Response.class, user, classifyBean);
    }

    @ApiOperation(value = "修改分类")
    @PostMapping("/updateClassify")
    public Response updateClassify(@CasUser @ApiIgnore EamUser user, @RequestBody ClassifyBean classifyBean) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "updateClassify", Response.class, user, classifyBean);
    }

    @ApiOperation(value = "删除分类")
    @PostMapping("/deleteClassify")
    public Response deleteClassify(@CasUser @ApiIgnore EamUser user, @RequestBody ClassifyBean classifyBean) {
        return ADOConnection.runTask(user.getCurrDs(), equipmentbackupservice, "deleteClassify", Response.class, user, classifyBean);
    }

    @SneakyThrows
    @ApiOperation(value = "下载模板")
    @GetMapping("template")
    public void template(HttpServletResponse response) {
        String path = "excel/BackMo.xlsx";
        ClassPathResource classPathResource = new ClassPathResource(path);
        Workbook book = WorkbookUtil.createBook(classPathResource.getInputStream());
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("备品备件模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        book.write(response.getOutputStream());
    }

    @SneakyThrows
    @ApiOperation(value = "导入")
    @PostMapping("import")
    public Response<String> importFile(@CasUser @ApiIgnore EamUser user, @RequestParam("file") MultipartFile file, @RequestParam("classifyId") String classify_id) {
        EasyExcel.read(file.getInputStream(), EquipmentBackup.class, new BackUpLinstener(equipmentbackupservice, user, classify_id)).sheet().doRead();
        return Response.success("导入成功");
    }

    @ApiOperation(value = "变更状态 0.草稿1.已启用2.已禁用")
    @GetMapping("changeStatus")
    public Response changeStatus(@CasUser @ApiIgnore EamUser user, @RequestParam("id") String id, @RequestParam("status") String status) {
        ADOConnection.runTask(user.getCurrDs(), factory -> {
            factory.getMapper(EquipmentBackupMapper.class).updateStatusById(status, id);
            return true;
        }, Boolean.class);
        return Response.success();
    }


    @ApiOperation(value = "外部接口查备件类型")
    @GetMapping("/queryEqBackUpType")
    public Response queryEqBackUpType() {
        List result = ADOConnection.runTask(getCurrDs(), factory -> {
            List<ClassifyDto> dtoList = factory.getMapper(EquipmentBackupMapper.class).queryAll();
            TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
            List<Tree<String>> treeList = TreeUtil.build(dtoList, "0", treeNodeConfig,
                    (treeNode, node) -> {
                        node.setId(treeNode.getId());
                        node.setParentId(treeNode.getParentId());
                        node.setName(treeNode.getName());
                        // 扩展属性 ...
                        node.putExtra("sort", treeNode.getSort());
                    });
            return treeList;
        }, List.class);
        return Response.success(result);
    }

    @ApiOperation(value = "全路径树构建")
    @GetMapping("/buildFullPathTree")
    public Response buildFullPathTree() {
        ClassifyDto topNode = new ClassifyDto();
        topNode.setParentId("");
        topNode.setId("0");
        topNode.setFullPathCode("0");
        topNode.setFullPathName("根节点");
        topNode.setName("根节点");
        List<ClassifyDto> result = ADOConnection.runTask(getCurrDs(), factory -> {
            List<ClassifyDto> dtoList = factory.getMapper(EquipmentBackupMapper.class).queryAll();
            dtoList.add(topNode);
            TreeUtils<ClassifyDto, String> tree = new TreeUtils<>(
                    dtoList, ClassifyDto::getId,
                    ClassifyDto::getParentId,
                    ClassifyDto::setChildren);
            tree.build();
            List<ClassifyDto> relist = dtoList.stream().filter(f -> f.getId().equals("0")).collect(Collectors.toList());

            BiConsumer<ClassifyDto, Object> fullCodeCons = (t, u) ->t.setFullPathCode(String.valueOf(u));
            BiConsumer<ClassifyDto, Object> fullNameCons = (t, u) ->t.setFullPathName(String.valueOf(u));
            tree.buildFullPath(relist, relist.get(0),
                    ClassifyDto::getFullPathCode,
                    ClassifyDto::getFullPathName,
                    ClassifyDto::getName,
                    fullCodeCons,
                    fullNameCons,
                    ClassifyDto::getChildren);

            return relist;
        }, List.class);
//        rediu(result, topNode);
        return Response.success(result);
    }

    public void rediu(List<ClassifyDto> children, ClassifyDto parent) {

        for (ClassifyDto classifyDto : children) {
            if (children.stream().noneMatch(item -> parent.getId().equals(item.getParentId()))) {
                classifyDto.setFullPathCode(classifyDto.getId());
                classifyDto.setFullPathName(classifyDto.getName());
            } else{
                classifyDto.setFullPathCode(StrUtil.join("/", parent.getFullPathCode(), classifyDto.getId()));
                classifyDto.setFullPathName(StrUtil.join("/", parent.getFullPathName(), classifyDto.getName()));
            }
            if (CollUtil.isNotEmpty(classifyDto.getChildren())) {
                rediu(classifyDto.getChildren(), classifyDto);
            }
        }
    }


    @ApiOperation(value = "外部接口导入备品备件")
    @PostMapping("/batchSaveEqBack")
    public Response batchSaveEqBack(@RequestBody List<EquipmentBackupDto> dtolist) {
        Response res = ADOConnection.runTask(getCurrDs(), factory -> {
            List<String> codes = dtolist.stream().map(EquipmentBackupDto::getCode).collect(Collectors.toList());
            List<String> dupCodelist = CommonUtils.getDuplicateElements(codes);
            if (CollUtil.isNotEmpty(dupCodelist)) {
                String joindupStr = dupCodelist.stream().collect(Collectors.joining(","));
//                Assert.isFalse(true, StrUtil.format("备件编号重复：{}", joindupStr));
                return Response.fail(10001, StrUtil.format("请求参数备件编号重复：{}", joindupStr));
            }

            List<EquipmentBackup> bulist = dtolist.stream().map(new Function<EquipmentBackupDto, EquipmentBackup>() {
                @Override
                public EquipmentBackup apply(EquipmentBackupDto equipmentBackupDto) {
                    EquipmentBackup convert = Convert.convert(EquipmentBackup.class, equipmentBackupDto);
                    convert.setOrigin("system_provision");
                    convert.setStatus("0");
                    convert.setIsBind("0");
                    return convert;
                }
            }).collect(Collectors.toList());
            return equipmentbackupservice.batchSaveEqBack(factory, bulist);
        }, Response.class);
        return res;
    }


}





















